#ifndef EXPERIMENTPLATEUI_H
#define EXPERIMENTPLATEUI_H

#include <QMap>
#include <QAction>
#include <QEvent>
#include <QKeyEvent>
#include <QMenu>
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QWidget>
#include <QVBoxLayout>
#include <QtCharts>
#include <QLineEdit>
#include <QKeyEvent>
#include <QListView>
#include <QPoint>
#include <QSpacerItem>
#include <QImage>

#include "DyelibraryService.h"
#include "dyelibraryui.h"
#include "global.h"
#include "SamplelibraryService.h"
#include "samplelibraryui.h"
#include "UiStruct.h"
#include "doubleclicked.h"
#include "maintain.h"
#include "standard.h"
#include "QPCRDB.h"
#include "ConfigFileService.h"
#include "customitemdelegrate.h"
#include "custommessagebox.h"
#include "customreactionplate.h"
#include "customcombobox.h"

QT_CHARTS_USE_NAMESPACE

namespace Ui {
class ExperimentPlateUi;
}

class ExperimentPlateUi : public QWidget
{
    Q_OBJECT

public:
    explicit ExperimentPlateUi(QWidget *parent = nullptr);
    ~ExperimentPlateUi();

signals:
    void previousEvent();
    void nextEvent();
    void saveEvent();
    void closePage();

public slots:
    void sampleClick(QTableWidgetItem*);
    void targetClick(QTableWidgetItem*);
    void samplebox(const int);
    void targetbox(const int);
    void filter(QAction*);
    void slot_DL_RcOnTw(QPoint);
    void doubleClickedTable(int, int);
    void sampleSettingBox(const int);
    void targetSettingBox(const int);
    void materialType(const int);
//    void changeSampleName(QModelIndex,QModelIndex,QVector<int>);
    void changeTargetName(QModelIndex,QModelIndex,QVector<int>);
    void rapidComboxChange(int);
    void slotMode(int);
    void slotTarget(int);
    void startMaterial();
    void copystartCountChanged(int);
    void slotUpdateTable(int);
    void doubleClickTypeChanged(int);
    void ShowTooltip(QModelIndex);
    void nextCallback();

    void slotChangeItemsColor();

protected:
    void keyPressEvent(QKeyEvent *event);

public:
    QList<QString> detailReporterBox;

    ReactionPlate sendReactionPlate();
    std::tuple<QString, ReactionPlate, QString> returnPageInfos(); // 返回页面信息
    bool hasPlateTargetContent(); // 返回反应板孔位是否为空状态

    void getPlateData(QString plateRemarks, ReactionPlate reactionPlate, QString canBi);
    void addSample();
    void addTarget();
    bool renderSample();
    void deleteSample();
    void deleteTarget();
    void tableClick();
    void targetQuantity();
    void clearTable();
    void sleep(int);
    void importSample();
    void importTarget();
    void slotActionSave();
    void paintStand();
    void defaultTarget();
    void defaultSample();
    void markTable();
    QColor selectColor(int, int);
    void updateTable();
    void readFromXML();
    bool readAndRenderTableRowColumnFromXML(QString consume);
    void startExpe();
    void updateTarget();
    void updateSample();
    void renderDataLabel();
    void slotGotoDetailTable();
    void slotGotoMaterialTable();
    void slotGotoTable();
    void slotRightExpanding();
    void slotLeftExpanding();
    void slotRestore();
    void slotFoldSampleList();
    void slotExtendSampleList();
    void slotFoldTargetList();
    void slotExtendTargetList();
    QString colorTostring(QColor);
    QColor stringToColor(QString);
    void slotFullScreen();
    void slotNormalScreen();
    void renderDetailTable();
    void renderStandTable(QString);
    void renderyingguangLine();
    void allComponentsInvalid(); // 所有组件失效
    void allComponentsValid(); // 所有组件生效
    void slotActionCopy();
    void slotActionPaste();
    void slotActionSetting();
    void slotActionExport();
    void slotSampleEdit();
    void slotStandCountLine();
    void slotStandCopyLine();
    void slotStandRadioBtn1();
    void slotStandRadioBtn2();
    void slotStandRadioBtn3();
    void slotStandRadioBtn4();
    void slotStandShowInfo();
    void slotStandNew();
    void slotStandConfirm();
    void updateTargetListInfo();
    void updateSampleListInfo();
    void targetInfoRenderTargetList();
    void sampleInfoRenderSampleList();
    void doubleClickCountChanged();
    void detailTableInfoRender();
    void allSelectTarget();
    void renderMaterial();

    void targetNumberCanClick();
    void targetNumberNotClick();

// repackage
private:
    QWidget* createLabelWidget();// 创建布局
    /*
     * 使用一个数组或一个字符串来存储标签
     * 使用QString::arg()函数来拼接字符串
     */
    QTableWidgetItem* createItem(int arow, int acolumn);// 创建表格

    void createAndAddReporterLabel();// 创建并添加标准品信息的标签

    static QLabel* createLabel(const QString& aText);// 创建标签对象

    /* 根据不同的方向和数量，给standIndex数组赋值为1 */
    void fillStandIndex(int standIndex[], int row, int column, bool horizontal);

    /*
    * 对重复的操作进行封装
    *row, column: 行数和列数; horizontal: 真则column; hasLetters: 是否声明标签; hasWidgetLabel: 是否设置布局; hasReporterLabel: 是否设置反应板报告基因
    * shouldSetStandTargetReporter: 是否设置标准品报告基因; shouldSetCellWidget: 是否设置孔位控件; hasUtil: 设置反应板报告基因的选择
    */
    void setStandLayout(int row, int column, bool horizontal, bool hasLetters, bool hasWidgetLabel, bool hasReporterLabel, bool shouldSetStandTargetReporter, bool shouldSetCellWidget, bool hasUtil);

    /* 设置反应板报告基因 */
    void addLabelsAll(QVBoxLayout *vLayout);

    /* 设置反应板报告基因 */
    void addLabelsUntilNull(QVBoxLayout *vLayout);

    void createTargetLabel(ReactionPlate &reactionPlate, int count, int l, int &p, bool whetherAlignCenter);

    /* 隐藏一些组件 */
    void hideComponents();

    /* 实例化一些对象 */
    void createObjects();

    /* 初始化一些数据 */
    void initData();

    /* 获取点数和复制品数 */
    int calculateTotalHoles();

    /* 设置"选择的孔位"的文本 */
    void setChooseText(QString num, int totalHoles);

    /* 用于从表格中获取下拉框控件 */
    QComboBox *getComboBoxFromTable(QTableWidget *table, int row, int column);

    void clearPlateInformation(); // 清空反应板信息
    void handlerStandPlate(int count, int ccount);

private:
    Ui::ExperimentPlateUi *ui;
    struct copyReactionPlate{
        Sample sampleName;
        Target targetReporter[20];
    };

    // 自定义提示框实例化
    CustomMessageBox *cusMsg{};
    // 反应板右键复制信息存储
    copyReactionPlate copyNameReporter;
    //    SampleWidget *samW;
    //    TargetWidget *tarW;

    // 反应板信息存储
    ReactionPlate reactionPlate;
    ReactionPlate renderSamplePlate;

    // flag[2] 是靶基因个数 flag[4]是靶基因后数字 删除靶基因后仅仅是减少个数(flag[2]，不减少靶基因名称后数字(flag[4])
    // flag[3] flag[5] 是样本
    // flag[0] flag[1] 没用上
    int flag[6] = {0, 0, 0, 0, 0, 0};

    // 渲染反应板时添加的布局
    QVBoxLayout *vLayout{};
    QWidget *widgetLabel{};
    QGridLayout *gLayout{};
    QPointer<QLabel> labelPtr; // 获取gLayout里面的label指针
    int wlkflag = 0;

    // 样本库染料库实例化
    SampleLibrary *sampleLibrary{};
    DyeLibrary *dyeLibrary{};

    // 反应板右键的菜单
    QMenu *tableMenu{};

    // 双击反应板弹窗实例化
    doubleClicked *view{};
    //    maintain *weihu;

    // 标准品界面实例化
    standard *stand{};

    // 存储染料库和样本库信息
    QList<QHash<QString,QString>> allDyeInfos;
    QList<QHash<QString,QString>> allSampleInfos;

    // 无关变量
    int import_sample = 0;
    int import_target = 0;

    // 快速设置样本下拉框内的输入框
    QLineEdit *sampleEdit{};

    // 反应板内有样本信息的孔位个数，在反应板下方的label显示
    int sampleCount = 0;

    // 反应板右键标准品设置存储反应板名称和信息
    QList<QString> standTargetName;
    QList<QString> standTargetReporter;


    int indexes[96][2]{};

    // 反应板右键标准品设置页面标准品曲线预览
    QChart *chart{};
    int standIndex[96]{};

    // 从配置文件里获取默认的报告基因和耗材类型
    QList<QString> targetTypeFromConfig;
    QList<QString> consumableFromConfig;

    // 配置文件里默认的反应板行列数
    int * sampleTableRowColumn{};

    // 实例化配置文件
    ConfigFileService *configService{};

    // 从配置文件获取默认染料
    QList<QHash<QString,QString>> dyeFromConfig;

    // 反应板信息过滤
    QAction *action_1{};
    QAction *action_2{};
    QAction *action_3{};

    // 反应板右键菜单
    QAction *action_print{};
    QAction *action_export{};
    QAction *action_setting{};
    QAction *actionCopy{};
    QAction *actionPaste{};

    // 查看菜单
    QMenu *menu{};

    // 存储现有的靶基因名称，用于判断靶基因名称重复
    QList<QString> targetName;

    // 对应双击反应板进行孔位设置的信息
    QString targetListInfo[96][7];
    QString sampleListInfo[96][2];

    // 无关
    QModelIndex normalIndex;

    // 复制品功能中复制的样本名信息
    QString copySampleName[96];
    int spinBoxNum{};

    int o = 0;

    // change定义一个list，用来存储标签
    QStringList rowLetters = {"A", "B", "C", "D", "E", "F", "G", "H"};

    // change 将重复的if-else语句用hashmap替代
    // 设置稀释比例
    QMap<QString, double> ratioMap = { // 初始化map
            {"1:2", 0.5},
            {"1:3", 0.333},
            {"1:4", 0.25},
            {"1:5", 0.2},
            {"1:6", 0.167},
            {"1:7", 0.143},
            {"1:8", 0.125},
            {"1:9", 0.111},
            {"1:10", 0.1},
            {"2x", 2},
            {"3x", 3},
            {"4x", 4},
            {"5x", 5},
            {"6x", 6},
            {"7x", 7},
            {"8x", 8},
            {"9x", 9},
            {"10x", 10}
    };

    QString str = "";
    // 样式
    QString style = "QComboBox {"
                    "font-size: 14px;"
                    "font-family: \"Alibaba PuHuiTi\";"
                    "background: transparent;"
                    "border:none;"
                    "}"
                    "/* combobox下拉菜单 */"
                    "QComboBox QAbstractItemView {"
                    "background: #fff;"
                    "border: none;"
                    "}"
                    "QComboBox QAbstractItemView::item {"
                    "height: 30px;"
                    "border: none;"
                    "padding: 0 5px;"
                    "}"
                    "/* 下拉菜单选中 */"
                    "QComboBox QAbstractItemView::item:selected {"
                    "color: #000;"
                    "border: none;"
                    "background: rgba(75, 154, 250, 0.2);"
                    "}"
                    "/* 取消虚线边框 */"
                    "QListView {"
                    "outline: 0px;"
                    "}";

    // 参比荧光
    QString canBi;
    // 备注
    QString plateRemarks;


};

#endif // EXPERIMENTPLATEUI_H
